﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;

namespace UnitTests
{
    
    
    /// <summary>
    ///This is a test class for SplitAndMergeTest and is intended
    ///to contain all SplitAndMergeTest Unit Tests
    ///</summary>
    [TestClass()]
    public class SplitAndMergeTest
    {

        public const string FILENAME = @"D:\Downloads\Games\UNI\Telerik\NetEssentials\Elian Kurtenkov\SampleIntermediateExam_2\SplitAndMergeBinFile\bin\Debug\Test.mp3";
        public const int ONE_MB = 1024 * 1024;

        private TestContext testContextInstance;
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        private string[] GetSplittedFilesNames(string filename)
        {
            string newFilePart1 = string.Format("{0}-part_1.{1}", filename.Split('.')[0], filename.Split('.')[1]);
            string newFilePart2 = string.Format("{0}-part_2.{1}", filename.Split('.')[0], filename.Split('.')[1]);
            return new string[] { newFilePart1, newFilePart2 };
        }

        private string GetProductFileName(string orig_fileName)
        {
            string[] nameParts = orig_fileName.Split('.');
            string outputFilename = string.Format("{0}-original.{1}", nameParts[0], nameParts[1]);
            return outputFilename;
        }

        [TestMethod()]
        public void SplitFilesExistTest()
        {
            string fileName = FILENAME;
            SplitAndMerge.SplitFile(fileName);
            string[] newFilenames = GetSplittedFilesNames(fileName);
            Assert.IsTrue(File.Exists(newFilenames[0]) && File.Exists(newFilenames[1]));
        }

        [TestMethod()]
        public void SplitFilesSizesTest()
        {
            string fileName = FILENAME;
            SplitAndMerge.SplitFile(fileName);
            string[] newFilenames = GetSplittedFilesNames(fileName);
            long file1_size, file2_size, original_file_zize;
            original_file_zize = (new FileInfo(fileName)).Length;
            file1_size = (new FileInfo(newFilenames[0])).Length;
            file2_size = (new FileInfo(newFilenames[1])).Length;
            bool fileSizezAreCorrect = file1_size + file2_size == original_file_zize &&
                (Math.Abs(file2_size - file1_size) <= 5000);
            Assert.IsTrue(fileSizezAreCorrect);

        }

        [TestMethod()]
        public void MergedFileExistTest()
        {
            string fileName = FILENAME;
            SplitAndMerge.MergeFilesToOriginal(fileName);
            string product_fileName = GetProductFileName(fileName);
            Assert.IsTrue(File.Exists(product_fileName));
        }

        [TestMethod()]
        public void MergedFileSizeTest()
        {
            string fileName = FILENAME;
            SplitAndMerge.MergeFilesToOriginal(fileName);
            string product_fileName = GetProductFileName(fileName);
            long original_file_size = (new FileInfo(fileName)).Length;
            long product_file_size = (new FileInfo(product_fileName)).Length;
            Assert.AreEqual(original_file_size, product_file_size);
        }

        [TestMethod()]
        public void MergedFileEqualsOriginalTest()
        {
            bool areEqual = true;
            string fileName = FILENAME;
            SplitAndMerge.MergeFilesToOriginal(fileName);
            string product_fileName = GetProductFileName(fileName);
            using (FileStream readStream_orig = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                using (FileStream readStream_product = new FileStream(product_fileName, FileMode.Open, FileAccess.Read))
                {
                    byte[] orig_buffer = new byte[ONE_MB];
                    byte[] product_buffer = new byte[ONE_MB];
                    while (true)
                    {
                        int bytesRead = readStream_orig.Read(orig_buffer, 0, ONE_MB);
                        if (bytesRead == 0)
                        {
                            break;
                        }
                        readStream_product.Read(product_buffer, 0, ONE_MB);
                        for (int i = 0; i < bytesRead; i++)
                        {
                            if (orig_buffer[i] != product_buffer[i])
                            {
                                areEqual = false;
                                break;
                            }
                        }
                    }
                }
            }
            Assert.IsTrue(areEqual);
        }
    }
}
